package mysgoog.pattern.attack;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.*;

import mysgoog.board.Board;
import mysgoog.bot.*;
import mysgoog.gtp.*;
import mysgoog.pattern.Matcher;
import mysgoog.pattern.Storage.ValuePair;
import mysgoog.pattern.Storage.VertexValue;
import mysgoog.pattern.influence.InfluencePatternLoader;
import mysgoog.util.BoardUtil;
/**
* @author Fu, Zhongyang
*/
public class AttackPatternMatcher implements Matcher
{

    private final int patternBoardSize = 8;
    private final int patternBoardSizeNum = 64;
    private final int patternNum = 4;

    private final int LEFT_UP = 0;
    private final int RIGHT_UP = 1;
    private final int LEFT_DOWN = 2;
    private final int RIGHT_DOWN = 3;

    private int[][] patternPos = null;

    public Map<Integer, Map<String, ValuePair>> patternMap;
  
    
    public AttackPatternMatcher()
    {
        patternMap = new HashMap<Integer, Map<String, ValuePair>>();
        try {
			InfluencePatternLoader.load(patternMap, "pattern\\aa_attackpats.dbpattern");
			InfluencePatternLoader.load(patternMap, "pattern\\attack.dbpattern");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}        
    }


	@Override
	public List<VertexValue> getMatch(Board b, Color player, List<VertexValue> moves) {
		Color[] board = b.getBoard();
		for (int key:patternMap.keySet()){
			int row = key / Config.getBoardSize();
			int column = key % Config.getBoardSize();
			getMatch(row, column, patternMap.get(key), board, player, moves);
		}
		return moves;
	}
	
	//for test
	public List<VertexValue> getMatch(Color[] board, Color player, List<VertexValue> moves) {		
		for (int key:patternMap.keySet()){
			int row = key / Config.getBoardSize();
			int column = key % Config.getBoardSize();
			getMatch(row, column, patternMap.get(key), board, player, moves);
		}
		return moves;
	}
	
	
	
	private void getMatch(int row, int column, Map<String, ValuePair> map, Color[] board, Color player, List<VertexValue> moves){
		Color[] board90 = BoardUtil.rotateBoard(Config.getBoardSize(), Config.getBoardSize(), board, 90);
		Color[] board270 = BoardUtil.rotateBoard(Config.getBoardSize(), Config.getBoardSize(), board, 270);
		Color[] board180 = BoardUtil.rotateBoard(Config.getBoardSize(), Config.getBoardSize(), board, 180);
		
		for (int i = -1; i < Config.getBoardSize() - row; i++){
			for (int j = -1; j < Config.getBoardSize() - column; j++){
				String subBoard;				
				subBoard = BoardUtil.getSubBoardString(i, j, row, column, board, player);	
				//subBoard = BoardUtil.getSubBoardString(0, 0, row, column, board, player);
				//if ((i == 0) && (j == 0)) System.out.println(subBoard);
				if (map.containsKey(subBoard)){		
					moves.add(				
							BoardUtil.changeVertex(parseValuePair(map.get(subBoard)), i, j));
				}
				subBoard = BoardUtil.getSubBoardString(i, j, row, column, board90, player);
				if (map.containsKey(subBoard)){					
					moves.add(
							BoardUtil.rotateVertex(
									BoardUtil.changeVertex(parseValuePair(map.get(subBoard)), i, j),
									Config.getBoardSize(),
									90));
				}				
				subBoard = BoardUtil.getSubBoardString(i, j, row, column, board180, player);
				if (map.containsKey(subBoard)){					
					moves.add(
							BoardUtil.rotateVertex(
									BoardUtil.changeVertex(parseValuePair(map.get(subBoard)), i, j),
									Config.getBoardSize(),
									180));
				}
				subBoard = BoardUtil.getSubBoardString(i, j, row, column, board270, player);
				if (map.containsKey(subBoard)){					
					moves.add(
							BoardUtil.rotateVertex(
									BoardUtil.changeVertex(parseValuePair(map.get(subBoard)), i, j),
									Config.getBoardSize(),
									270));
				}							
							
			}
		}
	}
	
	private VertexValue parseValuePair(ValuePair vp){
		VertexValue vv = new VertexValue(vp.x, vp.y, vp.value);
		return vv;
	}
		
}
